package com.roads.project.controller;

import java.util.ArrayList;
import java.util.List;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.roads.common.exception.ServiceException;
import com.roads.common.utils.StringUtils;
import com.roads.project.domain.ProBoq;
import com.roads.project.domain.ProInstitutionDetail;
import com.roads.project.service.IProBoqService;
import com.roads.project.service.IProInstitutionService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.roads.common.annotation.Log;
import com.roads.common.core.controller.BaseController;
import com.roads.common.core.domain.AjaxResult;
import com.roads.common.enums.BusinessType;
import com.roads.project.domain.ProBoqMeterage;
import com.roads.project.service.IProBoqMeterageService;
import com.roads.common.utils.poi.ExcelUtils;
import com.roads.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 计量清单Controller
 * 
 * @author nhp
 * @date 2021-12-14
 */
@RestController
@RequestMapping("/project/meterage")
public class ProBoqMeterageController extends BaseController {

    @Autowired
    private IProBoqMeterageService service;

    @Autowired
    private IProInstitutionService institutionService;

    @Autowired
    private IProBoqService boqService;

    /**
     * 查询列表
     */
    @PreAuthorize("@ss.hasPermi('project:boq:list')")
    @GetMapping("/list")
    public TableDataInfo list(ProBoqMeterage model) {
        startPage();
        List<ProBoqMeterage> list = service.selectModelList(model);
        return getDataTable(list);
    }

    /**
     * 导出
     */
    @PreAuthorize("@ss.hasPermi('project:boq:export')")
    @Log(title = "计量清单", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(ProBoqMeterage model) {
        List<ProBoqMeterage> list = service.selectModelList(model);
        ExcelUtils<ProBoqMeterage> util = new ExcelUtils<ProBoqMeterage>(ProBoqMeterage.class);
        return util.exportExcel(list, "计量清单数据");
    }

    /**
     * 获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('project:boq:query')")
    @GetMapping(value = "/{meterageBoqId}")
    public AjaxResult getInfo(@PathVariable("meterageBoqId") Long meterageBoqId) {
        return AjaxResult.success(service.getModelById(meterageBoqId));
    }

    @PostMapping("/getRemainderAmount")
    public AjaxResult getRemainderAmount(String meterageBoqCode) {
        ProBoqMeterage meterage = service.getModelByCode(meterageBoqCode);
        return AjaxResult.success(meterage.getRemainderAmount());
    }

    /**
     * 新增
     */
    @PreAuthorize("@ss.hasPermi('project:boq:add')")
    @Log(title = "计量清单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ProBoqMeterage model) {
        model.setCreateBy(getUsername());
        return toAjax(service.insert(model));
    }

    /**
     * 修改
     */
    @PreAuthorize("@ss.hasPermi('project:boq:edit')")
    @Log(title = "计量清单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ProBoqMeterage model) {
        model.setUpdateBy(getUsername());
        return toAjax(service.update(model));
    }

    /**
     * 删除
     */
    @PreAuthorize("@ss.hasPermi('project:boq:remove')")
    @Log(title = "计量清单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        // 如果计量清单参与计量，不能进行删除操作
        for (int i = 0; i < ids.length; i++) {
            ProBoqMeterage boqMeterage = service.getModelById(ids[0]);
            if ("0".equals(boqMeterage.getMeterageBoqType())) {
                int contractMeterageCount = service.getContractMeterageCount(boqMeterage.getMeterageBoqCode());
                if (contractMeterageCount > 0) {
                    return error("该计量清单已参与工程计量，不能进行删除操作");
                }
            } else {
                int changeMeterageCount = service.getChangeMeterageCount(boqMeterage.getMeterageBoqCode());
                if (changeMeterageCount > 0) {
                    return error("该计量清单已参与工程计量，不能进行删除操作");
                }
            }
        }
        return toAjax(service.deleteByIds(ids));
    }

    /**
     * 清空标段工程量清单
     *
     * @param institutionCode 标段编号
     * @return 结果
     */
    @Log(title = "计量清单", businessType = BusinessType.CLEAN)
    @PreAuthorize("@ss.hasPermi('project:boq:remove')")
    @PostMapping("/clean")
    public AjaxResult clean(String institutionCode) {
        if (service.hasPartakeMeterage(institutionCode)) {
            return error("该标段下的计量清单已参与工程计量，不能进行清空操作");
        }
        service.clean(institutionCode);
        return success();
    }

    @GetMapping("/importTemplate")
    public AjaxResult importTemplate() {
        ExcelUtils<ProBoqMeterage> utils = new ExcelUtils<>(ProBoqMeterage.class);
        return utils.importTemplateExcel("计量清单模板");
    }

    @PreAuthorize("@ss.hasPermi('project:boq:add')")
    @Log(title = "计量清单", businessType = BusinessType.GEN)
    @PostMapping("/generate")
    public AjaxResult generate(String institutionCode, String bigTypeValue) {
        // 已参与计量不能进行生成操作
        if (service.hasPartakeMeterage(institutionCode)) {
            return error("该标段下的计量清单已参与工程计量，不能进行生成操作");
        }
        // 判断该标段详情是否有起始桩号和终止桩号
        ProInstitutionDetail detailBid = institutionService.getDetailModelByInnerCode(institutionCode);
        if (StringUtils.isEmpty(detailBid.getBeginStation()) || StringUtils.isEmpty(detailBid.getEndStation())) {
            return AjaxResult.error(detailBid.getInstitutionName() + "未设置起始桩号或终止桩号");
        }
        return toAjax(service.generate(getUsername(), detailBid, institutionCode, bigTypeValue));
    }

    @PostMapping("/beforeImportValidate")
    public AjaxResult beforeImportValidate(String institutionCode) {
        // 判断该标段详情是否有起始桩号和终止桩号
        ProInstitutionDetail detailBid = institutionService.getDetailModelByInnerCode(institutionCode);
        if (StringUtils.isEmpty(detailBid.getBeginStation()) || StringUtils.isEmpty(detailBid.getEndStation())) {
            return AjaxResult.error(detailBid.getInstitutionName() + "未设置起始桩号或终止桩号");
        }
        // 判断该标段下是否有工程量清单
        ProBoq search = new ProBoq();
        search.setInstitutionCode(institutionCode);
        List<ProBoq> list = boqService.selectProBoqList(search);
        if (StringUtils.isNull(list) || list.size() == 0) {
            return AjaxResult.error(detailBid.getInstitutionName() + "未添加工程量清单");
        }
        return success();
    }

    @Log(title = "计量清单", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('project:boq:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, String institutionCode, boolean updateSupport) throws Exception {
        // 已参与计量不能进行生成操作
        if (service.hasPartakeMeterage(institutionCode) && !updateSupport) {
            throw new ServiceException("该标段下的计量清单已参与工程计量，不可以覆盖导入，只能数据续导");
        }
        List<ProBoqMeterage> easyExcelList = new ArrayList<>();
        StringBuffer analysisError = new StringBuffer();
        EasyExcel.read(file.getInputStream(), ProBoqMeterage.class, new AnalysisEventListener<ProBoqMeterage>() {
            @Override
            public void invoke(ProBoqMeterage proBoqMeterage, AnalysisContext analysisContext) {
                easyExcelList.add(proBoqMeterage);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
            @Override
            public void onException(Exception exception, AnalysisContext context) throws Exception {
                ExcelDataConvertException convertException = (ExcelDataConvertException)exception;
                analysisError.append("第" + convertException.getRowIndex() + "行，第" + convertException.getColumnIndex() + "列解析错误。</br>");
            }
        }).sheet().doRead();
        if (!StringUtils.isEmpty(analysisError)) {
            analysisError.insert(0, "很抱歉，导入失败！错误如下：</br>");
            return AjaxResult.success(analysisError.toString());
        }
        String message = service.importData(easyExcelList, institutionCode, updateSupport, getUsername());
        return AjaxResult.success(message);
    }
}
